/* -*- mode: c++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- */

#ifndef _UTILS_H_
#define _UTILS_H_

#include <string>
#include <vector>
#include <lua_wrap.h>

typedef bool (* dir_lookup_func_t) (const char *);

typedef std::vector<std::string> StringVector;

typedef unsigned long long Uint64;

#ifdef WIN32
  #define FS_SEP '\\'
#else
  #define FS_SEP '/'
#endif

extern int dir_lookup(const char        *path,
                      dir_lookup_func_t  func);

#define MSG_LEVEL_MESSAGE       0
#define MSG_LEVEL_DEBUG         1
#define MSG_LEVEL_WARNING       2
#define MSG_LEVEL_ERROR         3

extern bool g_verbose;

extern bool g_debug;

extern StringVector g_ignored_dir;

extern std::string g_root;

extern LuaWrap g_type_predicate_script;

extern int message(int level, const char *fmt, ...);

extern int get_cwd(std::string& path);

extern int get_abs_path(const char   *path,
                        std::string&  result);

extern int setup_root();

extern int setup_type_predicate_script();

extern void sleep_ms(int ms);

extern Uint64 get_ticks();

extern int read_entire_file(const char  *fn,
                            char       **result);

extern int adjust_path(const char   *path,
                       std::string&  result);

extern int test(const char *fn, char c);

extern int create_dir(const char *path);

#define PROC_ZERO               (0)
#define PROC_BIND_STDIN         (1)
#define PROC_BIND_STDOUT        (1 << 1)
#define PROC_BIND_STDERR        (1 << 2)

#define PROC_WAIT               0
#define PROC_NO_WAIT            1

#define PROC_EXIT_NORMAL        0
#define PROC_EXIT_SIGNAL        1
#define PROC_EXIT_CORE_DUMP     2

class Process {
public:
    // data struct sys-dep
    void               *_sys;

    void               *_user_data;

    Uint64              _run_ticks;

    Process();

    ~Process();

    bool run(std::string    name,
             StringVector   args,
             int            flags);

    bool running();

    // return bytes writed
    int write_stdin(const char *fmt, ...);

    // return bytes read
    int read_stdout(char *buf, int size);

    int read_stderr(char *buf, int size);

    // return -1 when sys-call error
    bool wait_proc(int  flag,
                   int *exited,
                   int *exit_type,
                   int *exit_value);

    void clean_resources();
};

#endif /* _UTILS_H_ */
